/*
 * Copyright 2010-2011 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package kr.co.talkofhousewife.config;

import javax.inject.Inject;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;



/**
 * Spring MVC Configuration.
 * Implements {@link WebMvcConfigurer}, which provides convenient callbacks that allow us to customize aspects of the Spring Web MVC framework.
 * These callbacks allow us to register custom interceptors, message converters, argument resovlers, a validator, resource handling, and other things.
 * @author Keith Donald
 * @see WebMvcConfigurer
 */
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {


	@Inject
	private Environment environment;

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/").addResourceLocations("/resources/**");
	}

	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		configurer.enable();
	}


	@Bean
	public UrlBasedViewResolver setupViewResolver() {
		InternalResourceViewResolver resolver = new InternalResourceViewResolver();
//		 UrlBasedViewResolver resolver = new UrlBasedViewResolver();
		resolver.setPrefix("/WEB-INF/views/");
		resolver.setSuffix(".jsp");
		resolver.setViewClass(JstlView.class);

		return resolver;
	}


	@Override
	public void configureContentNegotiation( ContentNegotiationConfigurer configurer) {
		// Simple strategy: only path extension is taken into account
		configurer.favorPathExtension(true).ignoreAcceptHeader(true)
				.useJaf(false).defaultContentType(MediaType.TEXT_HTML)
				.mediaType("html", MediaType.TEXT_HTML)
				.mediaType("xml", MediaType.APPLICATION_XML)
				.mediaType("json", MediaType.APPLICATION_JSON);
	}


//    @Bean
//    public ViewResolver viewResolver() throws JAXBException {
//      Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
//      jaxb2Marshaller.setClassesToBeBound(UserList.class, User.class);
//      MarshallingView marshallingView = new MarshallingView(jaxb2Marshaller);
//
//      ContentNegotiatingViewResolver contentNegotiatingViewResolver = new ContentNegotiatingViewResolver();
//      contentNegotiatingViewResolver.setDefaultViews(Arrays.asList(new MappingJackson2JsonView(), marshallingView));
//      return contentNegotiatingViewResolver;
//    }


//	private void ContentNegotiatingViewResolver(ContentNegotiationManager manager) {
//          ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
//          resolver.setContentNegotiationManager(manager);
//	}


//
//	@Bean
//	public MarshallingHttpMessageConverter marshallingMessageConverter() {
//	    return new MarshallingHttpMessageConverter(
//	        jaxb2Marshaller(),
//	        jaxb2Marshaller()
//	    );
//	}
//
//	@Bean
//	public Jaxb2Marshaller jaxb2Marshaller() {
//	    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
//	    marshaller.setClassesToBeBound(User.class);
//
//	    return marshaller;
//	}



////	public Validator getValidator() {
////		LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
////		ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
////		//messageSource.setBasename("/WEB-INF/messages/validation");
////
////
//////		new Resource[] {
//////
////////				new ClassPathResource(env.getProperty("file_info"))
////////				,new ClassPathResource(env.getProperty("file_warn"))
////////				,new ClassPathResource(env.getProperty("file_error"))
//////				new ClassPathResource("properties/info.xml")
//////				,new ClassPathResource("properties/warn.xml")
//////				,new ClassPathResource("properties/error.xml")
//////				,new ClassPathResource("properties/db_info.xml")
//////
//////		}
//
//
//
//		if (environment.acceptsProfiles("embedded")) {
//			messageSource.setCacheSeconds(0);
//		}
//		factory.setValidationMessageSource(messageSource);
//		return factory;
//	}



//	/**
//	 * Replaces use of {@link MvcConfiguringPostProcessor}.
//	 */
//	@Override
//	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//
//		// List is initially empty. Create and configure what we need.
//		MappingJackson2HttpMessageConverter jmc = new MappingJackson2HttpMessageConverter();
//		jmc.setPrettyPrint(true);
//		converters.add(jmc);
//
//		Jaxb2RootElementHttpMessageConverter j2 = new Jaxb2RootElementHttpMessageConverter();
//		converters.add(j2);
//		return;
//	}


//	@Bean(name="contentNegotiatingViewResolver")
//	public ViewResolver getContentNegotiatingViewResolver( ContentNegotiationManager manager) {
//		ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
//		resolver.setContentNegotiationManager(manager);
//
//
//		return resolver;
//	}
//

	// Will map to a bean called "accounts/list" in "spreadsheet-views.xml"

//	@Autowired
//	ServletContext servletContext;
//
//	@Bean(name = "excelViewResolver")
//	public ViewResolver getXmlViewResolver() {
//		XmlViewResolver resolver = new XmlViewResolver();
//		resolver.setLocation(new ServletContextResource(servletContext,"/WEB-INF/spring/spreadsheet-views.xml"));
//		resolver.setOrder(1);
//		return resolver;
//	}
//
//
//
//	// Will map to the JSP page: "WEB-INF/views/accounts/list.jsp"
//
//	@Bean(name = "jspViewResolver")
//	public ViewResolver getJspViewResolver() {
//
//		InternalResourceViewResolver resolver = new InternalResourceViewResolver();
//
//		resolver.setPrefix("WEB-INF/views");
//
//		resolver.setSuffix(".jsp");
//
//		resolver.setOrder(2);
//
//		return resolver;
//
//	}
//
//
//	  public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
//	    configurer.favorPathExtension(false).
//	            favorParameter(true).
//	            favorPathExtension(true).
//	            parameterName("mediaType").
//	            ignoreAcceptHeader(true).
//	            useJaf(false).
////	            defaultContentType(MediaType.APPLICATION_JSON).
//	            mediaType("html", MediaType.TEXT_HTML).
//	            mediaType("xml", MediaType.APPLICATION_XML).
//	            mediaType("json", MediaType.APPLICATION_JSON);
//	  }
//
//


//	  private List<View> DEFAULTVIEW() {
////
//	    return Arrays.<View>asList(new MappingJackson2JsonView(), new MarshallingView(new Jaxb2Marshaller()));
//////
//	  }
//
//	    @Bean
//	    public ViewResolver viewResolver(ContentNegotiationManager manager) throws JAXBException {
//
////	      Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
////	      jaxb2Marshaller.setClassesToBeBound(User.class,UserList.class);
////	      MarshallingView marshallingView = new MarshallingView(jaxb2Marshaller);
//
//	      ContentNegotiatingViewResolver contentNegotiatingViewResolver = new ContentNegotiatingViewResolver();
//
////		  contentNegotiatingViewResolver.setContentNegotiationManager(manager);
////		  contentNegotiatingViewResolver.setViewResolvers((List<ViewResolver>) setupViewResolver());
////	      contentNegotiatingViewResolver.setDefaultViews(Arrays.<View>asList(new MappingJackson2JsonView(), new MarshallingView(jaxb2Marshaller)));
//
////		    contentNegotiatingViewResolver.setDefaultViews(DEFAULTVIEW());
//
//
//
//		    List<View> l = new ArrayList<View>();
//		    l.add(new MappingJackson2JsonView());
////		    l.add(new MarshallingView(new XStreamMarshaller()));
//		    l.add(new MarshallingView());
//
//
//
//		    contentNegotiatingViewResolver.setDefaultViews(l);
//
//	      return contentNegotiatingViewResolver;
//	    }












	// implementing WebMvcConfigurer

//	public void addInterceptors(InterceptorRegistry registry) {
//		registry.addInterceptor(new AccountExposingHandlerInterceptor());
//		registry.addInterceptor(new DateTimeZoneHandlerInterceptor());
//		registry.addInterceptor(new UserLocationHandlerInterceptor());
//		registry.addInterceptor(new DeviceResolverHandlerInterceptor());
//	}
//
//	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
//		argumentResolvers.add(new AccountHandlerMethodArgumentResolver());
//		argumentResolvers.add(new DateTimeZoneHandlerMethodArgumentResolver());
//		argumentResolvers.add(new LocationHandlerMethodArgumentResolver());
//		argumentResolvers.add(new FacebookHandlerMethodArgumentResolver(environment.getProperty("facebook.appId"), environment.getProperty("facebook.appSecret")));
//		argumentResolvers.add(new DeviceHandlerMethodArgumentResolver());
//	}

//	public void addResourceHandlers(ResourceHandlerRegistry registry) {
//		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
//	}



	// additional webmvc-related beans

//	/**
//	 * ViewResolver configuration required to work with Tiles2-based views.
//	 */
//	@Bean
//	public ViewResolver viewResolver() {
//		UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
//		viewResolver.setViewClass(TilesView.class);
//		return viewResolver;
//	}
//
//	/**
//	 * Configures Tiles at application startup.
//	 */
//	@Bean
//	public TilesConfigurer tilesConfigurer() {
//		TilesConfigurer configurer = new TilesConfigurer();
//		configurer.setDefinitions(new String[] {
//			"/WEB-INF/layouts/tiles.xml",
//			"/WEB-INF/views/**/tiles.xml"
//		});
//		configurer.setCheckRefresh(true);
//		return configurer;
//	}

//	/**
//	 * Messages to support internationalization/localization.
//	 */
//	@Bean
//	public MessageSource messageSource() {
//		ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
//		messageSource.setBasename("/WEB-INF/messages/messages");
//		if (environment.acceptsProfiles("embedded")) {
//			messageSource.setCacheSeconds(0);
//		}
//		return messageSource;
//	}
//
//	/**
//	 * Supports FileUploads.
//	 */
//	@Bean
//	public MultipartResolver multipartResolver() {
//		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
//		multipartResolver.setMaxUploadSize(500000);
//		return multipartResolver;
//	}

	// custom argument resolver inner classes

//	private static class AccountHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
//
//		public boolean supportsParameter(MethodParameter parameter) {
//			return Account.class.isAssignableFrom(parameter.getParameterType());
//		}
//
//		public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest webRequest,
//				WebDataBinderFactory binderFactory) throws Exception {
//			Authentication auth = (Authentication) webRequest.getUserPrincipal();
//			return auth != null && auth.getPrincipal() instanceof Account ? auth.getPrincipal() : null;
//		}
//
//	}

//	private static class DateTimeZoneHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
//
//		public boolean supportsParameter(MethodParameter parameter) {
//			return DateTimeZone.class.isAssignableFrom(parameter.getParameterType());
//		}
//
//		public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest webRequest,
//				WebDataBinderFactory binderFactory) throws Exception {
//			return JodaTimeContextHolder.getJodaTimeContext().getTimeZone();
//		}
//
//	}

//	private static class LocationHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
//
//		public boolean supportsParameter(MethodParameter parameter) {
//			return Location.class.isAssignableFrom(parameter.getParameterType());
//		}
//
//		public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest webRequest,
//				WebDataBinderFactory binderFactory) throws Exception {
//			return webRequest.getAttribute(UserLocationHandlerInterceptor.USER_LOCATION_ATTRIBUTE, WebRequest.SCOPE_REQUEST);
//		}
//
//	}

}